package hyl.core.db;

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import hyl.core.MyFun;

/**
 * MyConnection 封装了Connection ,多了一些属性 它可以自动回收
 */
public class MyConnection implements Connection {
	private MyDataSource _ds;
	private Connection _conn;
	private int _id = -1;
	private long l上一回使用时间戳 = 0;

	public static final int I使用中 = 1;// 正常使用
	public static final int I空闲 = 0;
	public static final int I异常关闭 = 3;
	public static final int I超时 = 4;
	public int _i状态 = I空闲;

	public String toString() {
		StringBuilder sb = new StringBuilder("MyConnection:");
		sb.append("{id:").append(_id).append(',').append("i状态:").append(_i状态);
		sb.append(',').append("l使用时长:").append(getL使用时长());
		sb.append(',').append("是否关闭:").append(this.isExit()).append('}');
		return sb.toString();
	}

	public Long getL使用时长() {
		return MyFun.getMs() - l上一回使用时间戳;
	}

	public void showDataSourceInfo(String s) {
		_ds.showInfo(s);
	}

	public MyConnection(MyDataSource ds, Connection conn) {
		_conn = conn;
		_ds = ds;
		l上一回使用时间戳 = MyFun.getMs();
	}

	/** 绑定连接或更换链接时调用 */
	public void setConn(Connection conn) {
		_conn = conn;
	}

	public void reclock() {

		l上一回使用时间戳 = MyFun.getMs();
	}

	public int getId() {
		return _id;
	}

	public void setId(int id) {
		_id = id;
	}

	public Connection getConn() {
		l上一回使用时间戳 = MyFun.getMs();
		return _conn;
	}

	/** 关闭后立即归还到连接池,覆盖原来close方法 */
	public void close() {
		_ds.fv立即归还连接(this);
	}

	/** 系统退出时,伴随退出的函数 */
	public void exit() {
		try {
			if (!_conn.isClosed())
				_conn.close();
			_conn = null;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 判断连接是否有效
	 */
	public boolean isValid(int timeout) {
		try {
			// 5s内重新调用不用判断,超过5秒需要验证连接是否有效
			if (MyFun.getMs() < 5000 + l上一回使用时间戳)
				return true;
			return _conn.isValid(timeout);// 超时校验 5s内能不能连接成功的意思,能连接就是有效的
		} catch (SQLException e) {
			// System.out.println("毒毒毒毒毒");
			e.printStackTrace();
			return false;
		}
	}

	// ????
	public boolean isTimeout() {

		if (MyFun.getMs() > _ds.getI连接超时() + l上一回使用时间戳)
			return true;
		else
			return false;

	}

	public boolean isClosed() {
		return (this._i状态 == I空闲);

	}

	public boolean isExit() {
		try {
			if (_conn == null)
				return true;
			if (_conn.isClosed()) {
				_conn = null;
				return true;
			}
			return false;
		} catch (SQLException e) {
			return true;
		}
	}

	public void commit() throws SQLException {
		_conn.commit();
	}

	public void rollback() throws SQLException {
		_conn.rollback();
	}

	public Array createArrayOf(String intype, Object[] objes) throws SQLException {
		return _conn.createArrayOf(intype, objes);
	}

	public Statement createStatement() throws SQLException {
		return _conn.createStatement();
	}

	public boolean getAutoCommit() throws SQLException {
		return _conn.getAutoCommit();
	}

	public void setAutoCommit(boolean flag) throws SQLException {
		_conn.setAutoCommit(flag);
	}

	@Override
	public <T> T unwrap(Class<T> iface) throws SQLException {
		return _conn.unwrap(iface);
	}

	@Override
	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		return _conn.isWrapperFor(iface);
	}

	@Override
	public PreparedStatement prepareStatement(String sql) throws SQLException {
		return _conn.prepareStatement(sql);
	}

	@Override
	public CallableStatement prepareCall(String sql) throws SQLException {
		return _conn.prepareCall(sql);
	}

	@Override
	public String nativeSQL(String sql) throws SQLException {
		return _conn.nativeSQL(sql);
	}

	@Override
	public DatabaseMetaData getMetaData() throws SQLException {
		return _conn.getMetaData();
	}

	@Override
	public void setReadOnly(boolean readOnly) throws SQLException {
		_conn.setReadOnly(readOnly);
	}

	@Override
	public boolean isReadOnly() throws SQLException {
		return _conn.isReadOnly();
	}

	@Override
	public void setCatalog(String catalog) throws SQLException {
		_conn.setCatalog(catalog);
	}

	@Override
	public String getCatalog() throws SQLException {
		return _conn.getCatalog();
	}

	@Override
	public void setTransactionIsolation(int level) throws SQLException {
		_conn.setTransactionIsolation(level);
	}

	@Override
	public int getTransactionIsolation() throws SQLException {
		return _conn.getTransactionIsolation();
	}

	@Override
	public SQLWarning getWarnings() throws SQLException {
		return _conn.getWarnings();
	}

	@Override
	public void clearWarnings() throws SQLException {
		_conn.clearWarnings();
	}

	@Override
	public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
		return _conn.createStatement(resultSetType, resultSetConcurrency);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
			throws SQLException {
		return _conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
	}

	@Override
	public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
		return _conn.prepareCall(sql, resultSetType, resultSetConcurrency);
	}

	@Override
	public Map<String, Class<?>> getTypeMap() throws SQLException {
		return _conn.getTypeMap();
	}

	@Override
	public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
		_conn.setTypeMap(map);
	}

	@Override
	public void setHoldability(int holdability) throws SQLException {
		_conn.setHoldability(holdability);
	}

	@Override
	public int getHoldability() throws SQLException {
		return _conn.getHoldability();
	}

	@Override
	public Savepoint setSavepoint() throws SQLException {
		return _conn.setSavepoint();
	}

	@Override
	public Savepoint setSavepoint(String name) throws SQLException {
		return _conn.setSavepoint(name);
	}

	@Override
	public void rollback(Savepoint savepoint) throws SQLException {
		_conn.rollback(savepoint);
	}

	@Override
	public void releaseSavepoint(Savepoint savepoint) throws SQLException {
		_conn.releaseSavepoint(savepoint);
	}

	@Override
	public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
			throws SQLException {
		return _conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
			int resultSetHoldability) throws SQLException {
		return _conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
	}

	@Override
	public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
			int resultSetHoldability) throws SQLException {
		return _conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
		return _conn.prepareStatement(sql, autoGeneratedKeys);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
		return _conn.prepareStatement(sql, columnIndexes);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
		return _conn.prepareStatement(sql, columnNames);
	}

	@Override
	public Clob createClob() throws SQLException {
		return _conn.createClob();
	}

	@Override
	public Blob createBlob() throws SQLException {
		return _conn.createBlob();
	}

	@Override
	public NClob createNClob() throws SQLException {
		return _conn.createNClob();
	}

	@Override
	public SQLXML createSQLXML() throws SQLException {
		return _conn.createSQLXML();
	}

	@Override
	public void setClientInfo(String name, String value) throws SQLClientInfoException {
		_conn.setClientInfo(name, value);
	}

	@Override
	public void setClientInfo(Properties properties) throws SQLClientInfoException {
		_conn.setClientInfo(properties);
	}

	@Override
	public String getClientInfo(String name) throws SQLException {
		return _conn.getClientInfo(name);
	}

	@Override
	public Properties getClientInfo() throws SQLException {
		return _conn.getClientInfo();
	}

	@Override
	public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
		return _conn.createStruct(typeName, attributes);
	}

	@Override
	public void setSchema(String schema) throws SQLException {
		_conn.setSchema(schema);
	}

	@Override
	public String getSchema() throws SQLException {
		return _conn.getSchema();
	}

	@Override
	public void abort(Executor executor) throws SQLException {
		_conn.abort(executor);
	}

	@Override
	public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
		_conn.setNetworkTimeout(executor, milliseconds);
	}

	@Override
	public int getNetworkTimeout() throws SQLException {
		return _conn.getNetworkTimeout();
	}
}
